/*
 * AD9954 IO Driver source file
 */

#include <LPC11xx.h>
#include <stdbool.h>

#include "gpio.h"
#include "SSP.h"
#include "hw_ad9954.h"

extern void delayus(uint32_t us);

void ad9954_io_init(void)
{
	SSPInit(AD9954_SPI_PORT, SSP_ClockPolarity_Low, SSP_ClockPhase_RisingEdge);

	GPIOSetDir(AD9954_CTL_PORT_AND_POS_RST, GPIO_DIR_OUTPUT);
	GPIOSetDir(AD9954_CTL_PORT_AND_POS_UPDATE, GPIO_DIR_OUTPUT);
	GPIOSetDir(AD9954_CTL_PORT_AND_POS_PWRDWN, GPIO_DIR_OUTPUT);
	GPIOSetDir(AD9954_CTL_PORT_AND_POS_IOSYNC, GPIO_DIR_OUTPUT);
	GPIOSetDir(AD9954_CTL_PORT_AND_POS_OSK, GPIO_DIR_OUTPUT);
	GPIOSetDir(AD9954_CTL_PORT_AND_POS_PS0, GPIO_DIR_OUTPUT);
	GPIOSetDir(AD9954_CTL_PORT_AND_POS_PS1, GPIO_DIR_OUTPUT);

//	GPIOSetPullup (&AD9954_CTL_RST_IOCON, GPIO_Pullup_Mode_Inactive);
//	GPIOSetPullup (&AD9954_CTL_UPDATE_IOCON, GPIO_Pullup_Mode_Inactive);
//	GPIOSetPullup (&AD9954_CTL_PWRDWN_IOCON, GPIO_Pullup_Mode_Inactive);
//	GPIOSetPullup (&AD9954_CTL_IOSYNC_IOCON, GPIO_Pullup_Mode_Inactive);
//	GPIOSetPullup (&AD9954_CTL_OSK_IOCON, GPIO_Pullup_Mode_Inactive);
//	GPIOSetPullup (&AD9954_CTL_PS0_IOCON, GPIO_Pullup_Mode_Inactive);
//	GPIOSetPullup (&AD9954_CTL_PS1_IOCON, GPIO_Pullup_Mode_Inactive);

	GPIOSetValue(AD9954_CTL_PORT_AND_POS_RST, 0);
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_UPDATE, 0);
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_PWRDWN, 0);
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_IOSYNC, 0);
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_OSK, 0);
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_PS0, 0);
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_PS1, 0);

	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_hwrst(void)
{
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_RST, 1);
	delayus(200);
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_RST, 0);
}

void ad9954_update(void)
{
	while(SSPBusy(AD9954_SPI_PORT));
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_UPDATE, 1);
	//delayus(200);
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_UPDATE, 0);
}

void ad9954_pwrdwn_set(bool set)
{
	set ? GPIOSetValue(AD9954_CTL_PORT_AND_POS_PWRDWN, 1) : GPIOSetValue(AD9954_CTL_PORT_AND_POS_PWRDWN, 0);
}

void ad9954_iosync(void)
{
	while(SSPBusy(AD9954_SPI_PORT));
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_IOSYNC, 1);
	delayus(200);
	GPIOSetValue(AD9954_CTL_PORT_AND_POS_IOSYNC, 0);
}

void ad9954_osk_set(bool set)
{
	set ? GPIOSetValue(AD9954_CTL_PORT_AND_POS_OSK, 1) : GPIOSetValue(AD9954_CTL_PORT_AND_POS_OSK, 0);
}

void ad9954_ps0_set(bool set)
{
	set ? GPIOSetValue(AD9954_CTL_PORT_AND_POS_PS0, 1) : GPIOSetValue(AD9954_CTL_PORT_AND_POS_PS0, 0);
}

void ad9954_ps1_set(bool set)
{
	set ? GPIOSetValue(AD9954_CTL_PORT_AND_POS_PS1, 1) : GPIOSetValue(AD9954_CTL_PORT_AND_POS_PS1, 0);
}

void ad9954_cfr1_write(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_CFR1_BASE);
	SSPSend(AD9954_SPI_PORT, data, 4);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_cfr1_read(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_CFR1_BASE|0x80);
	SSPReceive(AD9954_SPI_PORT, data, 4);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_cfr2_write(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_CFR2_BASE);
	SSPSend(AD9954_SPI_PORT, data, 3);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_cfr2_read(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_CFR2_BASE|0x80);
	SSPReceive(AD9954_SPI_PORT, data, 3);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_asf_write(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_ASF_BASE);
	SSPSend(AD9954_SPI_PORT, data, 3);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_asf_read(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_ASF_BASE|0x80);
	SSPReceive(AD9954_SPI_PORT, data, 2);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_arr_write(uint8_t data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_ARR_BASE);
	SSPSendByte(AD9954_SPI_PORT, data);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_arr_read(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_ARR_BASE|0x80);
	SSPReceiveByte(AD9954_SPI_PORT, data);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_ftw0_write(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_FTW0_BASE);
	SSPSend(AD9954_SPI_PORT, data, 4);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_ftw0_read(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_FTW0_BASE|0x80);
	SSPReceive(AD9954_SPI_PORT, data, 4);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_pow0_write(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_POW0_BASE);
	SSPSend(AD9954_SPI_PORT, data, 2);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_pow0_read(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_POW0_BASE|0x80);
	SSPReceive(AD9954_SPI_PORT, data, 2);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_ftw1_write(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_FTW1_BASE);
	SSPSend(AD9954_SPI_PORT, data, 4);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_ftw1_read(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_FTW1_BASE|0x80);
	SSPReceive(AD9954_SPI_PORT, data, 4);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_rscw0_write(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_RSCW0_BASE);
	SSPSend(AD9954_SPI_PORT, data, 4);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_rscw0_read(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_RSCW0_BASE|0x80);
	SSPReceive(AD9954_SPI_PORT, data, 5);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_rscw1_write(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_RSCW1_BASE);
	SSPSend(AD9954_SPI_PORT, data, 4);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_rscw1_read(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_RSCW1_BASE|0x80);
	SSPReceive(AD9954_SPI_PORT, data, 5);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_rscw2_write(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_RSCW2_BASE);
	SSPSend(AD9954_SPI_PORT, data, 4);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_rscw2_read(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_RSCW2_BASE|0x80);
	SSPReceive(AD9954_SPI_PORT, data, 5);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_rscw3_write(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_RSCW3_BASE);
	SSPSend(AD9954_SPI_PORT, data, 4);
	SSPDeselect(AD9954_SPI_PORT);
}

void ad9954_rscw3_read(uint8_t *data)
{
	SSPSelect(AD9954_SPI_PORT);
	SSPSendByte(AD9954_SPI_PORT, AD9954_RSCW3_BASE|0x80);
	SSPReceive(AD9954_SPI_PORT, data, 5);
	SSPDeselect(AD9954_SPI_PORT);
}
